package com.central.apps.service.impl;

import com.central.app.common.util.DateUtils;
import com.central.app.service.HandlerService;
import com.central.apps.common.constant.ProjectPlanConstant;
import com.central.apps.common.util.MapCustomUtils;
import com.central.apps.entity.MpxjBean;
import com.central.apps.entity.MpxjTaskBean;
import com.central.apps.service.TableService;
import com.central.apps.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigInteger;
import java.util.*;

/**
 * 任务接口实现类
 *
 * @author 李大超
 * @date 2023/3/11
 */
@Slf4j
@Service
public class TaskServiceImpl implements TaskService {

    @Autowired
    private HandlerService handlerService;
    @Autowired
    private TableService tableService;

    private Integer recordId = 1;

    @Override
    public void updateRecordId(Integer proId) throws Exception {
        // 查询项目对应的顶级任务
        List<Map<String, Object>> taskList = handlerService.findBySql("select id from gq_scheduleplantask where parentId = 0 and proid = " + proId);
        Map<String, Object> taskMap = taskList.get(0);
        Integer taskId = MapUtils.getInteger(taskMap,"id");

        // 递归修正任务对应的记录id
        recordId = 1;
        recursiveTaskTree(proId, taskId);
    }

    @Override
    public void updParentId(Integer proId) throws Exception {
        // 更新父级任务
        handlerService.updateBySql("update gq_scheduleplantask set haschild = 0 where haschild = 1 and proid = " + proId);
        // 查询最新数据
        List<Map<String, Object>> taskList = handlerService.findBySql("select * from gq_scheduleplantask where proid = " + proId + " order by recordId");

        int len = taskList.size();
        for (int i = 0; i < len; i++) {
            Map<String, Object> taskMap = taskList.get(i);

            if (i+1 == len) {
                break;
            }

            int level = (int) taskMap.get("level");
            for (int j = i + 1; j < len; j++) {
                Map<String, Object> nextTaskMap = taskList.get(j);
                int nextLevel = (int) nextTaskMap.get("level");

                if (level >= nextLevel) {
                    break;
                }

                if (level+1 == nextLevel) {
                    // 更新父级任务
                    handlerService.updateBySql("update gq_scheduleplantask set haschild = 1 where haschild = 0 and id = " + taskMap.get("id") + " and proid = " + proId);
                    // 更新子级任务
                    handlerService.updateBySql("update gq_scheduleplantask set parentId = " + taskMap.get("id") + ", parentname = '" + taskMap.get("name") + "' where id = " + nextTaskMap.get("id"));
                }
            }
        }
    }

    @Override
    public void updPredecessors(Integer proId) throws Exception {
        // 查询年度计划信息
        List<Map<String, Object>> taskList = handlerService.findBySql("select * from gq_scheduleplantask where proid = " + proId + " order by recordId");

        // 组织WBS计划信息
        if (CollectionUtils.isNotEmpty(taskList)) {
            // 更新前置任务
            for (Map<String, Object> taskMap : taskList) {
                Integer taskId = MapUtils.getInteger(taskMap, "id");
                String depends = MapUtils.getString(taskMap, "depends");
                StringBuilder predecessorsStr = new StringBuilder();
                StringBuilder predecessorsdescStr = new StringBuilder();

                // 查询前置任务信息
                if (StringUtils.isNotEmpty(depends)) {
                    String[] tempArray = depends.split(",");

                    for (String tempStr : tempArray) {
                        if (tempStr.contains(":")) {
                            tempStr = tempStr.substring(0, tempStr.indexOf(":") - 1);
                        }
                        predecessorsStr.append("'");
                        predecessorsStr.append(tempStr);
                        predecessorsStr.append("'");
                        predecessorsStr.append(",");
                    }
                    predecessorsStr.deleteCharAt(predecessorsStr.length() - 1);

                    // 查询前置任务信息
                    List<Map<String, Object>> predecessorsList = handlerService.findBySql("select id, name from gq_scheduleplantask " +
                            " where proid = " + proId + " and recordId in (" + predecessorsStr.toString() + ")");

                    // 组织前置任务信息
                    if (CollectionUtils.isNotEmpty(predecessorsList)) {
                        predecessorsStr = new StringBuilder();
                        for (Map<String, Object> predecessorsMap : predecessorsList) {
                            int predecessors = (Integer) predecessorsMap.get("id");
                            String predecessorsdesc = (String) predecessorsMap.get("name");

                            predecessorsStr.append(predecessors);
                            predecessorsStr.append(",");

                            predecessorsdescStr.append(predecessorsdesc);
                            predecessorsdescStr.append(",");
                        }
                        predecessorsStr.deleteCharAt(predecessorsStr.length() - 1);
                        predecessorsdescStr.deleteCharAt(predecessorsdescStr.length() - 1);

                        handlerService.updateBySql("update gq_scheduleplantask set predecessors = '" + predecessorsStr.toString()
                                + "', predecessorsdesc = '" + predecessorsdescStr + "' where id = " + taskId);
                    }
                }
            }
        }
    }

    @Override
    public String delTask(Integer proId, Integer taskId) throws Exception {
        // 判断任务状态
        List<Map<String, Object>> list = handlerService.findBySql("select status from gq_scheduleplantask where proId = " + proId + " and id = " + taskId);
        String status = MapUtils.getString(list.get(0), "status");

        if (!"未开始".equals(status)) {
            return "任务已经开工或者完工, 不允许删除!";
        }

        list = handlerService.findBySql("select id from gq_scheduleplantask where proId = " + proId + " and parentId = " + taskId);
        if (CollectionUtils.isNotEmpty(list)) {
            return "该任务存在子任务，请先删除子任务!";
        }

        list = handlerService.findBySql("select id from gq_scheduleplantask where proId = " + proId + " and  and CONCAT(',',predecessors,',') like '%," + taskId + ",%' and predecessors is not null");
        if (CollectionUtils.isNotEmpty(list)) {
            return "该任务是前置任务，请先删除关联后置任务!";
        }

        // 删除任务
        handlerService.updateBySql("delete from gq_scheduleplantask where proId = " + proId + " and id = " + taskId);

        // 更新任务RecodeId
        this.updateRecordId(proId);

        // TODO 统计项目任务信息
//        taskStatisticsService.taskStatistics(proId);

        return null;
    }

    @Override
    public Map<String, Object> viewTask(Integer proId, Integer taskId) throws Exception {
        List<Map<String, Object>> list = handlerService.findBySql("select t.* from gq_scheduleplantask t where t.proid = " + proId + " and t.id =" + taskId);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public MpxjBean viewPlan(Integer proId) throws Exception {
        // 查询年度计划信息
        List<Map<String, Object>> taskList = handlerService.findBySql("select * from gq_scheduleplantask where proid = " + proId + " order by recordId");

        // 组织WBS计划信息
        if (CollectionUtils.isNotEmpty(taskList)) {
            return combinePlanBean(taskList);
        }

        return null;
    }

    @Override
    public MpxjBean modifyPlan(MpxjBean mpxjBean, Integer proId) throws Exception {
        Integer[] delTaskIds = mpxjBean.getDeletedTaskIds();
        if (delTaskIds != null && delTaskIds.length > 0) {
            StringBuilder sb = new StringBuilder();
            for (int delTaskId : delTaskIds) {
                sb.append(delTaskId).append(",");
            }
            sb.deleteCharAt(sb.length()-1);

            handlerService.updateBySql("delete from gq_scheduleplantask where id in ("+ sb.toString() + ")");
        }

        List<MpxjTaskBean> mpxjTaskBeanList = mpxjBean.getTasks();
        if (CollectionUtils.isNotEmpty(mpxjTaskBeanList)) {
            this.dealTask(mpxjBean, mpxjTaskBeanList, proId);
        }

        // 查询最新的年度计划信息
        return this.viewPlan(proId);
    }

    @Override
    public String importPlan(MultipartFile file, Integer proId) throws Exception {
//        // 4.分别处理mpp/json
//        if (filename.toLowerCase(Locale.ROOT).endsWith("json")) {
//            // 解析文件流获取json文件详细
//            MpxjBean mpxjBean = ProjectPlanUtils.getMpxjBean(file);
//
//            // 插入项目进度计划任务信息
//            List<MpxjTaskBean> mpxjTaskBeanList = mpxjBean.getTasks();
//            if (CollectionUtils.isNotEmpty(mpxjTaskBeanList)) {
//                // 校验是否顶层是项目信息
//                MpxjTaskBean tempTaskBean = mpxjTaskBeanList.get(0);
//                String name = tempTaskBean.getName();
//
//                List<Map<String, Object>> tmpList = handlerService.findBySql("select pronum, proname, subjectno from gq_proaccount where id = "+ projectId);
//                if (CollectionUtils.isEmpty(tmpList)) {
//                    json.put("msg", "进度计划对应项目信息不存在, 请核对项目信息是否正确");
//                    return json.toString();
//                } else {
//                    String projectName = (String) tmpList.get(0).get("proname");
//
//                    if (!name.equals(projectName)) {
//                        json.put("msg", "顶层项目名称信息不存在, 请仔细校对项目名称信息");
//                        return json.toString();
//                    }
//                }
//
//                // 校验是否存在多个顶级信息
//                int count = 0;
//                for (MpxjTaskBean taskBean : mpxjTaskBeanList) {
//                    int level = taskBean.getLevel();
//                    if (level == 0) {
//                        count++;
//                    }
//                }
//
//                if (count > 1) {
//                    json.put("msg", "顶层信息只能存在一条(即顶层信息为项目信息), 请重新进行调整");
//                    return json.toString();
//                }
//
//                // 重新组织数据
//                combineTaskInfo(mpxjTaskBeanList);
//
//                // 导入保存数据
//                this.dealTask(mpxjBean, mpxjTaskBeanList, projectId, "pro", false);
//            }
//        } else if (filename.toLowerCase(Locale.ROOT).endsWith("mpp")) {
//            // 解析文件流获取mpp文件详细
//            List<TaskBean> taskBeanList = ProjectPlanUtils.getTaskList(file);
//
//            if (CollectionUtils.isNotEmpty(taskBeanList)) {
//                // 校验是否顶层是项目信息
//                TaskBean tempTaskBean = taskBeanList.get(0);
//                String name = tempTaskBean.getName();
//
//                List<Map<String, Object>> tmpList = handlerService.findBySql("select pronum, proname, personincharge, proleader from gq_proaccount where id = "+ projectId);
//
//                if (CollectionUtils.isEmpty(tmpList)) {
//                    json.put("msg", "进度计划对应项目信息不存在, 请核对项目信息是否正确");
//                    return json.toString();
//                } else {
//                    String projectName = (String) tmpList.get(0).get("proname");
//
//                    if (!name.equals(projectName)) {
//                        json.put("msg", "project文件中顶层项目名称信息不存在, 请仔细校对项目名称信息");
//                        return json.toString();
//                    }
//                }
//
//                // 校验是否存在多个顶级信息
//                int count = 0;
//                for (TaskBean taskBean : taskBeanList) {
//                    int level = taskBean.getLevel();
//                    if (level == 1) {
//                        count++;
//                    }
//                }
//
//                if (count > 1) {
//                    json.put("msg", "project文件中顶层信息只能存在一条(即顶层信息为项目信息), 请重新进行调整");
//                    return json.toString();
//                }
//
//                // 导入保存数据
//                String pronum = (String) tmpList.get(0).get("pronum");
//                String subjectno = (String) tmpList.get(0).get("subjectno");
//                Integer personincharge = (Integer) tmpList.get(0).get("personincharge");
//                Integer proleader = (Integer) tmpList.get(0).get("proleader");
//                this.dealTask(taskBeanList, projectId, pronum, subjectno, personincharge, proleader);
//            }
//        }
        return null;
    }

    @Override
    public String exportPlan(Integer proId) throws Exception {
        return null;
    }

    @Override
    public MpxjBean viewBaseLine(Integer proId) throws Exception {
        // 组织WBS数据list
        List<Map<String, Object>> list = combineList(proId);
        // 组织并返回WBS树形数据
        return combinePlanBean(list);
    }

    @Override
    public String judgeMilestone(Integer proId, MpxjBean mpxjBean) throws Exception {
        List<MpxjTaskBean> mpxjTaskBeanList = mpxjBean.getTasks();
        if (CollectionUtils.isNotEmpty(mpxjTaskBeanList)) {
            List<MpxjTaskBean> mlList = new ArrayList<>();
            // 组织里程碑list
            for (MpxjTaskBean mpxjTaskBean : mpxjTaskBeanList) {
                if (mpxjTaskBean.getMlid() > 0) {
                    mlList.add(mpxjTaskBean);
                }
            }

            if (CollectionUtils.isNotEmpty(mlList)) {

            }
        }
        return null;
    }

    @Override
    public void insertChgInfo(Map<Integer, Integer> relateMap, String toTableName, String idFieldName, List<Map<String, Object>> chgList,
                                 Map<String, Object> setValues, List<String> filterFields, boolean isUpdate, String fromTableName,
                                 boolean isFilterTemp, String filterFiledName, boolean isFilterParent, String parentFieldName) throws Exception {
        for (Map<String, Object> chgMap : chgList) {
            if (isFilterTemp) {
                String isTempTask = MapUtils.getString(chgMap, filterFiledName);

                if ("1".equals(isTempTask)) {
                    continue;
                }
            }

            // 获取旧的ID
            Integer oldId = MapUtils.getInteger(chgMap, idFieldName);
            if (oldId == 0) {
                // 组织新建任务信息
                Map<String, Object> map = MapCustomUtils.combineMap(chgMap, filterFields);
                // 手工赋值任务信息
                map.putAll(setValues);

                if (isFilterParent) {
                    Integer parentId = MapUtils.getInteger(map, parentFieldName);
                    if (parentId > 0) {
                        for (Map<String, Object> tempChgMap : chgList) {
                            Integer id = MapUtils.getInteger(tempChgMap, "id");
                            if (parentId.equals(id)) {
                                map.put(parentFieldName, MapUtils.getInteger(tempChgMap, idFieldName));
                                break;
                            }
                        }
                    }
                }

                // 插入信息
                BigInteger newId = (BigInteger) handlerService.insert(toTableName, map);

                Integer id = MapUtils.getInteger(chgMap, "id");
                relateMap.put(id, newId.intValue());

                // 更新任务数据
                chgMap.put(idFieldName, newId);
                if (isUpdate) {
                    handlerService.update(fromTableName, chgMap);
                }
            }
        }
    }

    @Override
    public void updateDeleteChgInfo(Map<Integer, Integer> relateMap, Map<String, String> relateConvertMap, List<Map<String, Object>> fromTaskList, List<Map<String, Object>> toTaskList,
                                 List<String> filterFields, String toTaskTableName, boolean isUpdMilestone, String fromTaskIdFieldName, List<String> expFields,
                                    boolean isFilterParent, String parentFieldName) throws Exception {
        // 修改&删除任务
        for (Map<String, Object> toTaskMap : toTaskList) {
            // 过滤存在的任务数据
            Map<String, Object> taskMap = judgeExist(fromTaskList, toTaskMap, fromTaskIdFieldName, expFields);
            if (taskMap != null) {
                String isExists = MapUtils.getString(taskMap, "isExists");
                if (StringUtils.isEmpty(isExists)) {
                    // 组织项目计划任务更新数据
                    Map<String, Object> map = MapCustomUtils.combineMap(taskMap, filterFields);

                    // 对应关系转换
                    if (relateConvertMap != null && relateConvertMap.isEmpty()) {
                        for (Map.Entry<String, String> entry : relateConvertMap.entrySet()) {
                            relateMap.put(MapUtils.getInteger(taskMap, entry.getKey()), MapUtils.getInteger(taskMap, entry.getValue()));
                        }
                    }

                    if (isFilterParent) {
                        // 转换父级ID
                        if (taskMap.get(parentFieldName) != toTaskMap.get(parentFieldName)) {
                            Integer parentId = MapUtils.getInteger(taskMap, parentFieldName);
                            if (parentId > 0) {
                                for (Map<String, Object> fromTaskMap : fromTaskList) {
                                    Integer id = MapUtils.getInteger(fromTaskMap, "id");
                                    if (parentId.equals(id)) {
                                        map.put(parentFieldName, MapUtils.getInteger(fromTaskMap, fromTaskIdFieldName));
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    map.put("id", MapUtils.getInteger(toTaskMap, "id"));
                    handlerService.update(toTaskTableName, map);

                    if (isUpdMilestone) {
                        Integer mlId = MapUtils.getInteger(toTaskMap, "mlid");
                        if (mlId > 0) {
                            Date endTime = (Date) MapUtils.getObject(taskMap, "endTime");
                            Date mlEndTime = (Date) MapUtils.getObject(toTaskMap, "endTime");

                            if (endTime.after(mlEndTime)) {
                                Map<String, Object> updMap = new HashMap<>();
                                updMap.put("id", mlId);
                                updMap.put("startTime", MapUtils.getObject(taskMap, "startTime"));
                                updMap.put("endTime", MapUtils.getObject(taskMap, "endTime"));
                                updMap.put("duration", MapUtils.getObject(taskMap, "duration"));
                                handlerService.update("gq_pblmilestone", updMap);
                            }
                        }
                    }
                }
            } else {
                // 删除项目计划任务
                handlerService.updateBySql("delete from " + toTaskTableName + " where id = " + MapUtils.getInteger(toTaskMap, "id"));
            }
        }
    }

    @Override
    public void updateTaskInfo(String tableName, String queryConditon, String levelFieldName) throws Exception {
        // 更新任务记录id
        this.updateRecordId(tableName, queryConditon);
        // 更新任务父级id
        this.updParentId(tableName, queryConditon, levelFieldName);
        // 更新任务前置
        this.updPredecessors(tableName, queryConditon);
    }

    @Override
    public void updateRecordId(String tableName, String queryConditon) throws Exception {
        // 查询项目对应的顶级任务
        Map<String, Object> taskMap = handlerService.findOneBySql("select id from " + tableName + " where parentId = 0 and " + queryConditon);

        if (taskMap != null && !taskMap.isEmpty()) {
            Integer taskId = MapUtils.getInteger(taskMap, "id");

            // 递归修正任务对应的记录id
            recordId = 1;
            recursiveTaskTree(tableName, queryConditon, taskId);
        }
    }

    @Override
    public void updParentId(String tableName, String queryConditon, String levelFieldName) throws Exception {
        // 更新是否存在子级
        handlerService.updateBySql("update " + tableName + " set haschild = 0 where haschild = 1 and " + queryConditon);
        // 查询最新数据
        List<Map<String, Object>> taskList = handlerService.findBySql("select * from " + tableName + " where 1 = 1 and " + queryConditon + " order by recordId");

        int len = taskList.size();
        for (int i = 0; i < len; i++) {
            Map<String, Object> taskMap = taskList.get(i);

            if (i + 1 == len) {
                break;
            }

            int level = MapUtils.getInteger(taskMap, levelFieldName);
            for (int j = i + 1; j < len; j++) {
                Map<String, Object> nextTaskMap = taskList.get(j);
                int nextLevel = MapUtils.getInteger(nextTaskMap, levelFieldName);

                if (level >= nextLevel) {
                    break;
                }

                if (level + 1 == nextLevel) {
                    // 更新父级任务
                    handlerService.updateBySql("update " + tableName + " set haschild = 1 where haschild = 0 and id = " + taskMap.get("id"));
                    // 更新子级任务
                    handlerService.updateBySql("update " + tableName + " set parentId = " + taskMap.get("id") + ", parentname = '" + taskMap.get("name") + "' where id = " + nextTaskMap.get("id"));
                }
            }
        }
    }

    @Override
    public void updPredecessors(String tableName, String queryConditon) throws Exception {
        // 查询任务信息
        List<Map<String, Object>> taskList = handlerService.findBySql("select * from " + tableName + " where 1 = 1 and " + queryConditon + " order by recordId");

        // 组织WBS计划信息
        if (CollectionUtils.isNotEmpty(taskList)) {
            // 更新前置任务
            for (Map<String, Object> taskMap : taskList) {
                Integer taskId = MapUtils.getInteger(taskMap, "id");
                String depends = MapUtils.getString(taskMap, "depends");
                StringBuilder predecessorsStr = new StringBuilder();
                StringBuilder predecessorsdescStr = new StringBuilder();

                // 查询前置任务信息
                if (StringUtils.isNotEmpty(depends)) {
                    String[] tempArray = depends.split(",");

                    for (String tempStr : tempArray) {
                        if (tempStr.contains(":")) {
                            tempStr = tempStr.substring(0, tempStr.indexOf(":") - 1);
                        }
                        predecessorsStr.append("'");
                        predecessorsStr.append(tempStr);
                        predecessorsStr.append("'");
                        predecessorsStr.append(",");
                    }
                    predecessorsStr.deleteCharAt(predecessorsStr.length() - 1);

                    // 查询前置任务信息
                    List<Map<String, Object>> predecessorsList = handlerService.findBySql("select id, name from " + tableName +
                            " where 1 = 1 and " + queryConditon + " and recordId in (" + predecessorsStr.toString() + ")");

                    // 组织前置任务信息
                    if (CollectionUtils.isNotEmpty(predecessorsList)) {
                        predecessorsStr = new StringBuilder();
                        for (Map<String, Object> predecessorsMap : predecessorsList) {
                            int predecessors = (Integer) predecessorsMap.get("id");
                            String predecessorsdesc = (String) predecessorsMap.get("name");

                            predecessorsStr.append(predecessors);
                            predecessorsStr.append(",");

                            predecessorsdescStr.append(predecessorsdesc);
                            predecessorsdescStr.append(",");
                        }
                        predecessorsStr.deleteCharAt(predecessorsStr.length() - 1);
                        predecessorsdescStr.deleteCharAt(predecessorsdescStr.length() - 1);

                        handlerService.updateBySql("update " + tableName + " set predecessors = '" + predecessorsStr.toString()
                                + "', predecessorsdesc = '" + predecessorsdescStr + "' where id = " + taskId);
                    }
                }
            }
        }
    }

    @Override
    public void updParentIdAndPredecessors(String app, String tableName, String queryConditon) throws Exception {
        List<Map<String, Object>> list = handlerService.findBySql("select * from " + tableName + " where 1 = 1 and " + queryConditon);
        List<Map<String, Object>> tempList = new ArrayList<>(list);

        for (Map<String, Object> map : list) {
            String parentId = MapUtils.getString(map, "parentId");
            String predecessors = MapUtils.getString(map, "predecessors");

            if ("0".equals(parentId)) {
                continue;
            }

            StringBuilder sb = new StringBuilder();
            boolean flag = false;
            for (Map<String, Object> tempMap : tempList) {
                String id = MapUtils.getString(tempMap, "id");
                String taskId = MapUtils.getString(tempMap, "taskid");

                if (parentId.equals(taskId)) {
                    flag = true;
                    map.put("parentId", id);
                }

                if (StringUtils.isNotEmpty(predecessors) && predecessors.contains(taskId)) {
                    sb.append(id).append(",");
                }
            }

            if (StringUtils.isNotEmpty(sb)) {
                sb.deleteCharAt(sb.length() - 1);
                map.put("predecessors", sb.toString());
            }
        }

        handlerService.batchSave(app, tableName, list);
    }

    @Override
    public void dealChgInfo(String app, String chgFieldName, Integer chgId, String fromTableName1, String fromIdFieldName1, String fromTableName2, String toUpdTableName,
                            String toNewTableName, String toDelTableName, List<Map<String, Object>> fromList, List<Map<String, Object>> toList,
                            Map<String, List<String>> convertMap, List<String> expFields) throws Exception {
        if (CollectionUtils.isNotEmpty(toList)) {
            // 新增信息
            List<Map<String, Object>> newList = new ArrayList<>();
            for (Map<String, Object> fromMap : fromList) {
                Integer oldId = MapUtils.getInteger(fromMap, fromIdFieldName1);
                if (oldId == 0) {
                    Map<String, Object> addMap = tableService.convertMap(fromTableName1, toNewTableName, fromMap, convertMap, null);
                    addMap.put(chgFieldName, chgId);// 变更id
                    newList.add(addMap);
                }
            }

            if (CollectionUtils.isNotEmpty(newList)) {
                handlerService.batchInsert(fromTableName1, toNewTableName, newList);
            }

            // 修改&删除信息
            List<Map<String, Object>> updList = new ArrayList<>();
            List<Map<String, Object>> delList = new ArrayList<>();

            for (Map<String, Object> toMap : toList) {
                // 过滤存在的信息数据
                Map<String, Object> chgMap = judgeExist(fromList, toMap, fromIdFieldName1, expFields);
                if (chgMap != null) {
                    String isExists = MapUtils.getString(chgMap, "isExists");
                    if (StringUtils.isEmpty(isExists)) {
                        // 变更信息
                        Map<String, Object> addMap = tableService.convertMap(fromTableName1, toUpdTableName, chgMap, convertMap, null);
                        addMap.put(chgFieldName, chgId);// 变更id

                        for (Map.Entry<String, Object> chgEntry : chgMap.entrySet()) {
                            if (chgEntry.getKey().contains("old") && !chgEntry.getKey().equals(fromIdFieldName1)) {
                                addMap.put(chgEntry.getKey().replaceAll("old", ""), chgEntry.getValue());// 存储新的字段信息
                            }
                        }

                        updList.add(addMap);
                    }
                } else {
                    // 删除信息
                    Map<String, Object> addMap = tableService.convertMap(fromTableName2, toDelTableName, toMap, convertMap, null);
                    addMap.put(chgFieldName, chgId);// 变更id
                    delList.add(addMap);
                }
            }

            if (CollectionUtils.isNotEmpty(updList)) {
                handlerService.batchInsert(app, toUpdTableName, updList);
            }
            if (CollectionUtils.isNotEmpty(delList)) {
                handlerService.batchInsert(app, toDelTableName, delList);
            }
        } else {
            // 新增任务
            List<Map<String, Object>> newList = new ArrayList<>();
            for (Map<String, Object> fromMap : fromList) {
                Map<String, Object> addMap = tableService.convertMap(fromTableName1, toNewTableName, fromMap, convertMap, null);
                addMap.put(chgFieldName, chgId);// 变更id
                newList.add(addMap);
            }

            if (CollectionUtils.isNotEmpty(newList)) {
                handlerService.batchInsert(app, toNewTableName, newList);
            }
        }
    }

    @Override
    public void copyToMyTask(Integer proId) throws Exception {
        List<Map<String, Object>> taskPlan = handlerService.findBySql("select * from gq_scheduleplantask where proid = " + proId);
        List<Map<String, Object>> myTask = handlerService.findBySql("select * from gq_mytask where proid = " + proId);

        if (CollectionUtils.isEmpty(myTask)) {
            Map<String, List<String>> convertMap = new HashMap<>();
            convertMap.computeIfAbsent("id", key -> new ArrayList<>()).add("taskid");

            List<Map<String, Object>> insertList = new ArrayList<>();
            for (Map<String, Object> taskPlanMap : taskPlan) {
                Map<String, Object> addMap = tableService.convertMap("gq_scheduleplantask", "gq_mytask", taskPlanMap, convertMap, null);
                addMap.put("status", taskPlanMap.get("status"));
                insertList.add(addMap);
            }

            if (CollectionUtils.isNotEmpty(insertList)) {
                handlerService.batchInsert("mytaskApp", "gq_mytask", insertList);
            }
        } else {
            Map<String, List<String>> convertMap = new HashMap<>();
            convertMap.computeIfAbsent("id", key -> new ArrayList<>()).add("taskid");

            List<Map<String, Object>> insertList = new ArrayList<>();
            for (Map<String, Object> taskPlanMap : taskPlan) {
                Integer id = MapUtils.getInteger(taskPlanMap, "id");
                Map<String, Object> tempMyTaskMap = new HashMap<>();
                for (Map<String, Object> myTaskMap : myTask) {
                    Integer taskId = MapUtils.getInteger(myTaskMap, "taskid");
                    if (id.equals(taskId)) {
                        tempMyTaskMap  = myTaskMap;
                        break;
                    }
                }

                if (tempMyTaskMap != null && !tempMyTaskMap.isEmpty()) {
                    // 判断是否发生了变更
                    boolean isChange = MapCustomUtils.compareTask(taskPlanMap, tempMyTaskMap, null);

                    if (!isChange) {
                        continue;
                    }

                    // 更新我的任务信息
                    handlerService.update("gq_mytask", tempMyTaskMap);
                } else {
                    Map<String, Object> addMap = tableService.convertMap("gq_scheduleplantask", "gq_mytask", taskPlanMap, convertMap, null);
                    addMap.put("status", taskPlanMap.get("status"));
                    insertList.add(addMap);
                }
            }

            if (CollectionUtils.isNotEmpty(insertList)) {
                handlerService.batchInsert("mytaskApp", "gq_mytask", insertList);
            }

            for (Map<String, Object> myTaskMap : myTask) {
                Integer taskPlanId = MapUtils.getInteger(myTaskMap, "taskid");

                boolean isExists = false;
                for (Map<String, Object> taskPlanMap : taskPlan) {
                    Integer id = MapUtils.getInteger(taskPlanMap, "id");
                    if (id.equals(taskPlanId)) {
                        isExists = true;
                        break;
                    }
                }

                if (!isExists) {
                    handlerService.updateBySql("delete from gq_mytask where id = " + MapUtils.getInteger(myTaskMap, "id"));
                }
            }
        }

        // 更新父级ID
        myTask = handlerService.findBySql("select * from gq_mytask where proid = " + proId);

        if (CollectionUtils.isNotEmpty(myTask)) {
            List<Map<String, Object>> tempTask = new ArrayList<>(myTask.size());
            tempTask.addAll(myTask);

            for (Map<String, Object> myTaskMap : myTask) {
                Integer id = MapUtils.getInteger(myTaskMap, "id");
                Integer parentId = MapUtils.getInteger(myTaskMap, "parentId");

                for (Map<String, Object> tempMap : tempTask) {
                    Integer taskId = MapUtils.getInteger(tempMap, "taskid");
                    Integer tempId = MapUtils.getInteger(tempMap, "id");

                    if (parentId.equals(taskId)) {
                        Map<String, Object> updMap = new HashMap<>();
                        updMap.put("id", id);
                        updMap.put("parentId", tempId);

                        handlerService.update("gq_mytask", updMap);
                        break;
                    }
                }
            }
        }
    }

    @Override
    public void dealDeliverables(String app, String condition, String relateIdFieldName, String newTableName, String updTableName, String delTableName, String deliTableName,
                                 Map<String, Object> setValues, List<String> expFields, Map<String, List<String>> convertMap) throws Exception {
        // 新增交付物
        List<Map<String, Object>> deliList = handlerService.findBySql("select * from " + newTableName + " where 1 = 1 and " + condition);
        if (CollectionUtils.isNotEmpty(deliList)) {
            List<Map<String, Object>> insertList = new ArrayList<>();

            for (Map<String, Object> deliMap : deliList) {
                Map<String, Object> addMap = tableService.convertMap(newTableName, deliTableName, deliMap, convertMap, expFields);
                // 手工赋值信息
                if (setValues != null && !setValues.isEmpty()) {
                    addMap.putAll(setValues);
                }
                insertList.add(addMap);
            }

            if (CollectionUtils.isNotEmpty(insertList)) {
                handlerService.batchInsert(app, deliTableName, insertList);
            }
        }

        // 更新交付物
        deliList = handlerService.findBySql("select * from " + updTableName + " where 1 = 1 and " + condition);
        if (CollectionUtils.isNotEmpty(deliList)) {
            for (Map<String, Object> deliMap : deliList) {
                Integer id = MapUtils.getInteger(deliMap, relateIdFieldName);

                Map<String, Object> updMap = tableService.convertMap(updTableName, delTableName, deliMap);
                updMap.put("id", id);
                handlerService.update(delTableName, updMap);
            }
        }

        // 删除交付物
        deliList = handlerService.findBySql("select * from " + updTableName + " where 1 = 1 and " + condition);
        if (CollectionUtils.isNotEmpty(deliList)) {
            for (Map<String, Object> deliMap : deliList) {
                Integer id = MapUtils.getInteger(deliMap, relateIdFieldName);
                handlerService.updateBySql("delete from " + delTableName + " where id = " + id);
            }
        }
    }

    /**
     * 判断是否存在任务信息
     *
     * @param fromList
     * @param toMap
     * @param fromIdFieldName
     * @param expFields
     * @return
     */
    private Map<String, Object> judgeExist(List<Map<String, Object>> fromList, Map<String, Object> toMap, String fromIdFieldName, List<String> expFields) {
        Integer id = MapUtils.getInteger(toMap, "id");

        for (Map<String, Object> fromMap : fromList) {
            Integer relateId = MapUtils.getInteger(fromMap, fromIdFieldName);

            if (id.equals(relateId)) {
                boolean isChg = false;
                Map<String, Object> map = new HashMap<>();
                for (Map.Entry<String, Object> fromEntry : fromMap.entrySet()) {
                    if (expFields.contains(fromEntry.getKey())) {
                        continue;
                    }

                    map.putAll(fromMap);
                    for (Map.Entry<String, Object> toEntry : toMap.entrySet()) {
                        if ("parentId".equals(fromEntry.getKey())) {
                            if (fromIdFieldName.equals(toEntry.getKey()) && !fromEntry.getValue().equals(toEntry.getValue())) {
                                isChg = true;
                                map.put("oldparentname", fromMap.get("parentname"));
                                break;
                            }
                        } else {
                            if (fromEntry.getKey().equals(toEntry.getKey()) && !fromEntry.getValue().equals(toEntry.getValue())) {
                                isChg = true;
                                map.put("old" + toEntry.getKey(), toEntry.getValue());
                                break;
                            }
                        }
                    }
                }

                if (isChg) {
                    return map;
                }

                map.clear();
                map.put("isExists", "1");
                return map;
            }
        }

        return null;
    }

    /**
     * 组织WBS数据list
     *
     * @param proId
     */
    private List<Map<String, Object>> combineList(Integer proId) throws Exception {
        List<Map<String, Object>> list = new ArrayList<>();
        // 添加根节点数据
        list.add(combineRoot(proId));

        // 查询年度计划信息
        List<Map<String, Object>> taskList = handlerService.findBySql("select * from gq_pblmilestone where proid = " + proId + " order by startTime, endTime");
        int i = 2;
        for (Map<String, Object> taskMap : taskList) {
            // 根据来源表转化目标表对象
            Map<String, List<String>> convertMap = new HashMap<>();
            convertMap.computeIfAbsent("id", key -> new ArrayList<>()).add("mlid");

            Map<String, Object> mlMap = tableService.convertMap("gq_pblmilestone", "gq_scheduleplantask", taskMap, convertMap, null);
            mlMap.put("id", "tmp_" + i);
            mlMap.put("recordId", i);
            mlMap.put("level", 1);
            mlMap.put("parentLevel", 0);
            mlMap.put("parentId", 1);
            mlMap.put("hasChild", 0);
            mlMap.put("progress", 0);
            mlMap.put("unfinishprocess", 100);
            mlMap.put("delayduration", 0);
            mlMap.put("actduration", 0);
            mlMap.put("isissued", 0);
            mlMap.put("isMilestone", 1);

            list.add(mlMap);
            i++;
        }

        return list;
    }

    /**
     * 组织根节点数据
     *
     * @param proId 项目id
     * @return
     */
    private Map<String, Object> combineRoot(Integer proId) {
        // 查询项目信息
        List<Map<String, Object>> list = handlerService.findBySql("select * from gq_proaccount where id = " + proId);
        Map<String, Object> map = list.get(0);
        Map<String, Object> topMap = new HashMap<>();
        topMap.put("id", "tmp_1");
        topMap.put("name", MapUtils.getString(map, "proname"));
        topMap.put("manager", MapUtils.getString(map, "personincharge"));
        topMap.put("managername", MapUtils.getString(map, "picname"));
        topMap.put("deptcode", MapUtils.getString(map, "deptcode"));
        topMap.put("deptname", MapUtils.getString(map, "deptname"));
        topMap.put("proid", MapUtils.getString(map, "id"));
        topMap.put("subjectno", MapUtils.getString(map, "subjectno"));
        topMap.put("year", MapUtils.getString(map, "year"));
        topMap.put("personincharge", MapUtils.getString(map, "personincharge"));
        topMap.put("proleader", MapUtils.getString(map, "proleader"));
        topMap.put("recordId", 1);
        topMap.put("level", 0);
        topMap.put("parentLevel", -1);
        topMap.put("parentId", 0);
        topMap.put("hasChild", 1);
        topMap.put("progress", 0);
        topMap.put("unfinishprocess", 100);
        topMap.put("delayduration", 0);
        topMap.put("actduration", 0);
        topMap.put("isissued", 0);
        topMap.put("durationTimeUnit", "天");
        topMap.put("mlid", 0);
        topMap.put("isMilestone", 0);

        // 查询里程碑对应的时间间隔
        List<Map<String, Object>> mlList = handlerService.findBySql("select min(startTime) as startTime, max(endTime) as endTime from gq_pblmilestone where proid = " + proId);
        Map<String, Object> mlMap = mlList.get(0);
        String startTime = MapUtils.getString(mlMap, "startTime");
        String endTime = MapUtils.getString(mlMap, "endTime");

        topMap.put("startTime", mlMap.get("startTime"));
        topMap.put("endTime", mlMap.get("endTime"));

        // 计算工期
        long days = DateUtils.daysBetweenExpWeekEnd(startTime, endTime);
        topMap.put("duration", days);

        return topMap;
    }

    /**
     * 递归修正任务对应的记录id
     *
     * @param proId
     * @param taskId
     */
    private void recursiveTaskTree(Integer proId, Integer taskId) {
        // 查询对应的下级任务
        List<Map<String, Object>> taskList = handlerService.findBySql("select id from gq_scheduleplantask where parentId = " + taskId + " and proid =" + proId + " order by recordId");

        if (CollectionUtils.isNotEmpty(taskList)) {
            for (Map<String, Object> taskMap : taskList) {
                recordId++;
                Integer id = MapUtils.getInteger(taskMap, "id");

                // 更新任务记录id
                handlerService.updateBySql("update gq_scheduleplantask set recordId = " + recordId + " where id = " + id);

                // 递归修正任务对应的记录id
                recursiveTaskTree(proId, id);
            }
        }
    }

    /**
     * 递归修正任务对应的记录id
     *
     * @param tableName
     * @param queryConditon
     */
    private void recursiveTaskTree(String tableName, String queryConditon, Integer taskId) {
        // 查询对应的下级任务
        List<Map<String, Object>> taskList = handlerService.findBySql("select id from " + tableName + " where parentId = " + taskId + " and " + queryConditon + " order by recordId");

        if (CollectionUtils.isNotEmpty(taskList)) {
            for (Map<String, Object> taskMap : taskList) {
                recordId++;
                Integer id = MapUtils.getInteger(taskMap, "id");

                // 更新任务记录id
                handlerService.updateBySql("update " + tableName + "  set recordId = " + recordId + " where id = " + id);

                // 递归修正任务对应的记录id
                recursiveTaskTree(tableName, queryConditon, id);
            }
        }
    }

    /**
     * 组织年度计划WBS实体信息
     *
     * @param taskList
     * @return MpxjBean
     */
    private MpxjBean combinePlanBean(List<Map<String, Object>> taskList) throws Exception {
        if (CollectionUtils.isNotEmpty(taskList)) {
            // 组织项目文件主信息
            MpxjBean mpxjBean = new MpxjBean();
            mpxjBean.setSelectedRow(1);
            mpxjBean.setCanAdd(ProjectPlanConstant.CAN_ADD);
            mpxjBean.setCanWrite(ProjectPlanConstant.CAN_WRITE);
            mpxjBean.setCanWriteOnParent(ProjectPlanConstant.CAN_WRITE_ON_PARENT);
            mpxjBean.setZoom(ProjectPlanConstant.ZOOM);

            List<MpxjTaskBean> mpxjTaskBeanList = new LinkedList<>();
            for (Map<String, Object> taskMap : taskList) {
                // 组织项目任务信息
                MpxjTaskBean mpxjTaskBean = new MpxjTaskBean();
                mpxjTaskBean.setId(MapUtils.getString(taskMap, "id"));
                mpxjTaskBean.setName(MapUtils.getString(taskMap, "name"));
                mpxjTaskBean.setLevel(MapUtils.getInteger(taskMap, "level"));
                mpxjTaskBean.setDescription(MapUtils.getString(taskMap, "description"));
                mpxjTaskBean.setProgress(MapUtils.getInteger(taskMap, "progress"));
                mpxjTaskBean.setProgressByWorklog(ProjectPlanConstant.PROGRESS_BY_WORKLOG);

                mpxjTaskBean.setTypeId(MapUtils.getString(taskMap, "typeId"));
                mpxjTaskBean.setType(MapUtils.getString(taskMap, "type"));
                mpxjTaskBean.setManager(MapUtils.getInteger(taskMap, "manager"));
                mpxjTaskBean.setManagerName(MapUtils.getString(taskMap, "managername"));
                mpxjTaskBean.setStatus(MapUtils.getString(taskMap, "status"));
                mpxjTaskBean.setTaskLevel(MapUtils.getString(taskMap, "tasklevel"));
                mpxjTaskBean.setDepends(MapUtils.getString(taskMap, "depends"));
                mpxjTaskBean.setAssigns(MapUtils.getString(taskMap, "assigns"));
                mpxjTaskBean.setAssignsDesc(MapUtils.getString(taskMap, "assignsdesc"));

                // 处理时间相关属性
                if (taskMap.get("startTime") != null) {
                    Date startTime = (Date) taskMap.get("startTime");
                    mpxjTaskBean.setStart(startTime.getTime());
                }
                if (taskMap.get("endTime") != null) {
                    Date endTime = (Date) taskMap.get("endTime");
                    mpxjTaskBean.setEnd(endTime.getTime());
                }
                if (taskMap.get("actstarttime") != null) {
                    Date actStartTime = (Date) taskMap.get("actstarttime");
                    mpxjTaskBean.setActStart(actStartTime.getTime());
                }
                if (taskMap.get("actendtime") != null) {
                    Date actEndTime = (Date) taskMap.get("actendtime");
                    mpxjTaskBean.setActEnd(actEndTime.getTime());
                }

                mpxjTaskBean.setDuration(MapUtils.getInteger(taskMap, "duration"));
                mpxjTaskBean.setDurationTimeUnit(MapUtils.getString(taskMap, "durationTimeUnit"));
                mpxjTaskBean.setActDuration(MapUtils.getInteger(taskMap, "actduration"));

                mpxjTaskBean.setStartIsMilestone(ProjectPlanConstant.START_IS_MILESTONE);
                mpxjTaskBean.setEndIsMilestone(ProjectPlanConstant.END_IS_MILESTONE);
                String isMilestone = MapUtils.getString(taskMap, "isMilestone");
                if ("1".equals(isMilestone)) {
                    mpxjTaskBean.setEndIsMilestone(true);
                }

                Integer hasChild = MapUtils.getInteger(taskMap, "hasChild");
                mpxjTaskBean.setHasChild(hasChild == 1);

                mpxjTaskBean.setMlid(MapUtils.getInteger(taskMap, "mlid"));

                mpxjTaskBean.setCollapsed(ProjectPlanConstant.IS_COLLAPSED);
                mpxjTaskBean.setCanWrite(ProjectPlanConstant.CAN_WRITE);
                mpxjTaskBean.setCanAdd(ProjectPlanConstant.CAN_ADD);
                mpxjTaskBean.setCanDelete(ProjectPlanConstant.CAN_DELETE);
                mpxjTaskBean.setCanAddIssue(ProjectPlanConstant.CAN_ADD_ISSUE);
                mpxjTaskBean.setRelevance(0);

                mpxjTaskBeanList.add(mpxjTaskBean);
            }

            // 项目计划添加任务信息
            mpxjBean.setTasks(mpxjTaskBeanList);
            return mpxjBean;
        }

        return null;
    }

    /**
     * 处理项目进度计划信息
     *
     * @param mpxjBean WBS全部信息
     * @param mpxjTaskBeanList WBS任务信息
     * @param proId 项目id
     */
    private void dealTask(MpxjBean mpxjBean, List<MpxjTaskBean> mpxjTaskBeanList, Integer proId) throws Exception {
        // 查询项目台账信息
        List<Map<String, Object>> proList = handlerService.findBySql("select subjectno, personincharge, proleader, deptcode, deptname from gq_proaccount where id = "+ proId);
        Map<String, Object> proMap = proList.get(0);
        String subjectno = MapUtils.getString(proMap, "subjectno");
        Integer personincharge = MapUtils.getInteger(proMap, "personincharge");
        Integer proleader = MapUtils.getInteger(proMap, "proleader");
        String deptCode = MapUtils.getString(proMap, "deptcode");
        String deptName = MapUtils.getString(proMap, "deptname");

        int recordId = 1;
        for (MpxjTaskBean mpxjTaskBean : mpxjTaskBeanList) {
            String taskId = mpxjTaskBean.getId();
            String name = StringUtils.isEmpty(mpxjTaskBean.getName()) ? "" : mpxjTaskBean.getName();
            Integer level = mpxjTaskBean.getLevel() == null ? 0 : mpxjTaskBean.getLevel();
            String type = StringUtils.isEmpty(mpxjTaskBean.getTypeId()) ? "" : mpxjTaskBean.getTypeId();
            String typeDesc = StringUtils.isEmpty(mpxjTaskBean.getType()) ? "" : mpxjTaskBean.getType();
            String depends = StringUtils.isEmpty(mpxjTaskBean.getDepends()) ? "" : mpxjTaskBean.getDepends();
            Integer hasChild = mpxjTaskBean.isHasChild() ? 1 : 0;

            long start = mpxjTaskBean.getStart();
            long end = mpxjTaskBean.getEnd();
            String startTime = DateUtils.dateToStr(new Date(start), "yyyy-MM-dd HH:mm:ss");
            String endTime = DateUtils.dateToStr(new Date(end), "yyyy-MM-dd HH:mm:ss");
            String description = StringUtils.isEmpty(mpxjTaskBean.getDescription()) ? "" : mpxjTaskBean.getDescription();
            Integer duration = mpxjTaskBean.getDuration() == null ? 0 : mpxjTaskBean.getDuration();
            String durationTimeUnit = mpxjTaskBean.getDurationTimeUnit() == null ? "天" : mpxjTaskBean.getDurationTimeUnit();
            Integer manager = mpxjTaskBean.getManager() == null ? 0 : mpxjTaskBean.getManager();
            String managerName = StringUtils.isEmpty(mpxjTaskBean.getManagerName()) ? "" : mpxjTaskBean.getManagerName();
            Integer mlid = mpxjTaskBean.getMlid() == null ? 0 : mpxjTaskBean.getMlid();

            // 里程碑
            boolean isEndIsMilestone = mpxjTaskBean.isEndIsMilestone();
            String isMilestone = "0";
            if (isEndIsMilestone) {
                isMilestone = "1";
            }

            Map<String, Object> map = new HashMap<>(1);
            map.put("name", name);
            map.put("level", level);
            map.put("parentLevel", level-1);
            map.put("recordId", recordId);
            map.put("type", type);
            map.put("typeDesc", typeDesc);
            map.put("isMilestone", isMilestone);
            map.put("startTime", startTime);
            map.put("endTime", endTime);
            map.put("manager", manager);
            map.put("managername", managerName);
            map.put("description", description);
            map.put("duration", duration);
            map.put("durationTimeUnit", durationTimeUnit);
            map.put("hasChild", hasChild);
            map.put("mlid", mlid);

            map.put("proid", proId);
            map.put("subjectno", subjectno);
            map.put("personincharge", personincharge);
            map.put("proleader", proleader);
            map.put("deptcode", deptCode);
            map.put("deptname", deptName);
            map.put("depends", depends);

            if (taskId.startsWith("tmp_")) {
                map.put("status", "未开始");
                map.put("taskstatus", "未开始");
                map.put("unfinishprocess", 100);
                handlerService.insert("gq_scheduleplantask", map);
            } else {
                map.put("id", taskId);
                handlerService.update("gq_scheduleplantask", map);
            }

            recordId++;
        }

        // 重新整理父子关系
        this.updParentId(proId);

        // 更新前置任务信息
        this.updPredecessors(proId);
    }
}
